package com.cashmama.market.api.domain.service.impl;

import com.cashmama.market.api.domain.service.ApiTradeService;
import com.cashmama.market.api.infras.consts.RedisKeyConsts;
import com.cashmama.market.api.infras.enums.order.BillTypeEnum;
import com.cashmama.market.api.infras.exception.ApplicationException;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.google.common.collect.Lists;
import com.qianli.cashmama.trade.client.bill.BillQueryService;
import com.qianli.cashmama.trade.client.bill.request.BillListRequest;
import com.qianli.cashmama.trade.client.bill.response.BillListResponse;
import com.qianli.cashmama.trade.client.trade.TradeApplicationService;
import com.qianli.cashmama.trade.client.trade.TradeQueryService;
import com.qianli.cashmama.trade.client.trade.request.QueryTradesRequest;
import com.qianli.cashmama.trade.client.trade.request.UserLatestTradeQueryRO;
import com.qianli.cashmama.trade.client.trade.request.UserTradeListQueryRO;
import com.qianli.cashmama.trade.client.trade.response.TradeInfoRO;
import com.qianli.cashmama.trade.client.trade.response.TradeInfoResponse;
import com.qianli.cashmama.trade.client.trade.response.TradeListResponse;
import com.qianli.cashmama.trade.client.vo.BillVO;
import com.qianli.cashmama.trade.client.vo.TradeVO;
import com.qianli.cashmama.trade.common.enums.TradeStatusEnum;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.qianli.cashmama.trade.common.enums.BillPaidStatusEnum.CLEAR_REPAYMENT;

/**
 * @program: market-api
 * @description
 * @author: frank
 * @create: 2019-12-23 16:19
 **/
@Service
public class TradeIntegrationServiceImpl implements ApiTradeService {
    private static final Logger LOGGER = LoggerFactory.getLogger(TradeIntegrationServiceImpl.class);

    @Autowired
    private TradeQueryService tradeQueryService;
    @Autowired
    private BillQueryService billQueryService;
    @Autowired
    private TradeApplicationService tradeApplicationService;
    @Autowired
    private RedisClient redisClient;

    @Override
    public boolean isNewUser(String userCode, String merchantCode) {
        Boolean isNewUser = redisClient.get(RedisKeyConsts.IS_NEW_USER_USER_CODE, userCode, merchantCode);
        if (isNewUser != null) {
            LOGGER.info("isNewUser命中缓存,userCode:{},isNewUser:{}", userCode, isNewUser);
            return isNewUser;
        }
        if(StringUtils.isBlank(userCode) || StringUtils.isBlank(merchantCode)){
            return true;
        }
        try {
            isNewUser = true;
            UserTradeListQueryRO userTradeListQueryRO = new UserTradeListQueryRO();
            userTradeListQueryRO.setNeedCardInfo(false);
            userTradeListQueryRO.setUserCode(userCode);
            userTradeListQueryRO.setOrderStatus(null);
            userTradeListQueryRO.setMerchantCode(merchantCode);
            Response<List<TradeInfoRO>> listResponse = tradeQueryService.queryTradeListByUserCodeAndOrderStatus(userTradeListQueryRO);
            if(listResponse.isSuccess() && CollectionUtils.isNotEmpty(listResponse.getData())){
                for(TradeInfoRO tradeInfoRO : listResponse.getData()){
                    if(tradeInfoRO.getOrderStatus() == TradeStatusEnum.NORMAL_REPAYMENT
                            || tradeInfoRO.getOrderStatus() == TradeStatusEnum.EARLY_REPAYMENT
                            || tradeInfoRO.getOrderStatus() == TradeStatusEnum.OVERDUE_REPAYMENT){
                        isNewUser = false;
                        break;
                    }
                }
            }
            redisClient.set(RedisKeyConsts.IS_NEW_USER_USER_CODE, isNewUser, 5 * 60, userCode, merchantCode);
            return isNewUser;
        } catch (Exception e) {
            LOGGER.error("TradeIntegrationService查询失败,userCode:{},productCategory:{}", userCode, merchantCode, e);
            throw new ApplicationException("Query failed");
        }
    }

    @Override
    public List<BillVO> getRepayOrderBills(String userCode, String productCategory, String type) {
        UserLatestTradeQueryRO queryUserLatestTradeRequest = new UserLatestTradeQueryRO(userCode, productCategory);
        Response<TradeInfoRO> tradeInfoResponseResponse = tradeQueryService.queryUserLatestTradeByUserCodeAndTradeCategory(queryUserLatestTradeRequest);
        if (!tradeInfoResponseResponse.isSuccess()) {
            throw new ApplicationException(tradeInfoResponseResponse.getMsg());
        }
        if (tradeInfoResponseResponse.getData() == null) {
            return ListUtils.EMPTY_LIST;
        }
        //待还状态
        TradeStatusEnum[] pendingStatus = {TradeStatusEnum.REPAYMENT_WATTING, TradeStatusEnum.OVERDUE};
        if (!ArrayUtils.contains(pendingStatus, tradeInfoResponseResponse.getData().getOrderStatus())) {
            return ListUtils.EMPTY_LIST;
        }

        BillListRequest billListRequest = new BillListRequest();
        billListRequest.setTradeNo(tradeInfoResponseResponse.getData().getTradeNo());
        Response<BillListResponse> billListResponseList = billQueryService.queryBillList(billListRequest);
        if (!billListResponseList.isSuccess()) {
            throw new ApplicationException(billListResponseList.getMsg());
        }
        List<BillVO> billList = new ArrayList<>();
        if (billListResponseList.getData() == null) {
            return billList;
        }

        List<BillVO> billListResponse = billListResponseList.getData().getBillList();
        if (BillTypeEnum.ALL_BILL.getCode().equals(type)) {
            billList = billListResponse;
        } else {
            for (BillVO billVO : billListResponse) {
                if (billVO.getPaidStatus() != CLEAR_REPAYMENT) {
                    billList.add(billVO);
                }
            }
        }
        return billList;
    }

    @Override
    public List<BillVO> getRepayOrderBills(String tradeNo, String userCode, String productCategory, String type) {
        BillListRequest billListRequest = new BillListRequest();
        billListRequest.setTradeNo(tradeNo);
        Response<BillListResponse> billListResponseList = billQueryService.queryBillList(billListRequest);
        if (!billListResponseList.isSuccess()) {
            throw new ApplicationException(billListResponseList.getMsg());
        }
        List<BillVO> billList = new ArrayList<>();
        if (billListResponseList.getData() == null) {
            return billList;
        }

        List<BillVO> billListResponse = billListResponseList.getData().getBillList();
        if (BillTypeEnum.ALL_BILL.getCode().equals(type)) {
            billList = billListResponse;
        } else {
            for (BillVO billVO : billListResponse) {
                if (billVO.getPaidStatus() != CLEAR_REPAYMENT) {
                    billList.add(billVO);
                }
            }
        }
        return billList;
    }

    @Override
    public List<BillVO> getRepayOrderBills(List<String> billNos) {
        List<BillVO> billVOS = Lists.newArrayList();
        for (String billNo : billNos) {
            Response<BillVO> queryByBillNo = billQueryService.queryByBillNo(billNo);
            if (queryByBillNo.getData() != null && !Objects.equals(queryByBillNo.getData().getPaidStatus(), CLEAR_REPAYMENT)) {
                billVOS.add(queryByBillNo.getData());
            }
        }
        return billVOS;
    }

    @Override
    public void completeHighMark(String tradeNo) {
        Response response = tradeApplicationService.completeHighMarkV2(tradeNo);
        if (response == null || !response.isSuccess()) {
            throw new ApplicationException("Operation failed");
        }

    }

    @Override
    public List<TradeVO> getTradeListByUserCodes(List<String> userCodes) {
        QueryTradesRequest queryTradesRequest = new QueryTradesRequest();
        queryTradesRequest.setUserCodes(userCodes);
        Response<TradeListResponse> response = tradeQueryService.queryUserTradeListByUserCodes(queryTradesRequest);
        if (!response.isSuccess()) {
            throw new ApplicationException(response.getMsg());
        }
        return response.getData() != null ? response.getData().getTradeList() : Lists.newArrayList();
    }

    @Override
    public List<TradeVO> getTradeListByUserCode(String userCode) {
        Response<TradeListResponse> response = tradeQueryService.queryUserTradeListByUserCode(userCode);
        if (!response.isSuccess()) {
            throw new ApplicationException(response.getMsg());
        }
        if (response.getData() == null || CollectionUtils.isEmpty(response.getData().getTradeList())) {
            return Lists.newArrayList();
        }
        return response.getData().getTradeList();
    }

    @Override
    public List<BillVO> getBillListByUserCodes(List<String> userCodes) {
        Response<List<BillVO>> listResponse = billQueryService.queryByUserCodes(userCodes);
        if (!listResponse.isSuccess()) {
            throw new ApplicationException(listResponse.getMsg());
        }
        return listResponse.getData();
    }

    @Override
    public TradeInfoRO getTradeInfoByMerchantCodeAndUserCode(String merchantCode, String userCode) {
        return null;
    }

    @Override
    public List<TradeVO> getTradeInfoListByUserCode(String userCode) {
        Response<TradeListResponse> response = tradeQueryService.queryUserTradeListByUserCode(userCode);
        if(!response.isSuccess()){
            throw new ApplicationException(response.getMsg());
        }
        return response.getData().getTradeList();
    }

    @Override
    public TradeInfoResponse getTradeInfoByTradeNo(String tradeNo) {
        Response<TradeInfoResponse> response = tradeQueryService.queryByTradeNo(tradeNo);
        if(!response.isSuccess()){
            throw new ApplicationException(response.getMsg());
        }
        return response.getData();
    }
}
